//trait
use std::fmt::*;
struct Duck;
struct Pig;

trait Fly {
    fn fly(&self) -> bool {
        return true;
    }
}
impl Fly for Duck {
    fn fly(&self) -> bool {
        true
    }
}

impl Fly for Pig {
    fn fly(&self) -> bool {
        false
    }
}
fn fly_static<T: Fly>(s: T) -> bool {
    s.fly()
}

fn fly_dyn(s: &Fly) -> bool {
    s.fly()
}

struct Point {
    x: i32,
    y: i32,
}

impl Debug for Point {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(f, "Point{{x:{},y:{}}}", self.x, self.y)
    }
}


fn main() {
    let _pig = Pig;
    assert_eq!(fly_static::<Pig>(Pig), false);
    let _duck = Duck;
    assert_eq!(fly_static::<Duck>(Duck), true);

    assert_eq!(fly_dyn(&Pig), false);
    assert_eq!(fly_dyn(&Duck), true);

    let o = Point { x: 3, y: 10 };
    println!("{:?}", o);

  

}
